<?php

class AtendimentoService extends Model {

    /**
     * @var AtendimentoDao
     */
    private $atendimentoDao;
    /**
     * @var ClienteService
     */
    private $clienteService;
    /**
     * @var SetorService
     */
    private $setorService;
    /**
     * @var UsuarioService
     */
    private $usuarioService;
    /**
     * @var DepartamentoService
     */
    private $departamentoService;
    /**
     * @var MensagemService
     */
    private $mensagemService;
    /**
     * @var AvaliacaoService
     */
    private $avaliacaoService;

    /**
     * @property    FilterType
     */

    const PHONE_SECTOR = 'list-phone-sector';
    const PHONE_ALL = 'list-phone-all';
    const OWNER_PHONE_CALLED = 'list-myPhoneCalled';
    const LAST_20 = 'list-last20';
    const EXTERNAL_SECTOR = 'list-external-sector';
    const EXTERNAL_PRIORITY = 'list-external-priority';
    const OWNER_EXTERNAL_CALLED = 'list-myExternalCalled';
    const INTERNAL_SECTOR = 'list-internal-sector';
    const INTERNAL_ALL = 'list-internal-all';
    const INTERNAL_WAITING_CUSTOMER = 'list-internal-customer';
    const EXTERNAL_WAITING_CUSTOMER = 'list-myExternalCalledWaitingCustomer';
    const CANCELLED_WAITING_ANSWER = 'list-cancelled-waiting-answer';
    const CANCELLED_WAITING_CUSTOMER = 'list-cancelled-waiting-customer';
    const CANCELLED_CLOSED = 'list-cancelled-closed';

    public function injectDependencies() {
        $this->atendimentoDao = AtendimentoDao::getInstance();
        $this->clienteService = ClienteService::getInstance();
        $this->setorService = SetorService::getInstance();
        $this->usuarioService = UsuarioService::getInstance();
        $this->mensagemService = MensagemService::getInstance();
        $this->departamentoService = DepartamentoService::getInstance();
        $this->avaliacaoService = AvaliacaoService::getInstance();
    }

    /**
     * @method  savePhoneCalled
     *
     * Chama o Dao que faz a insercao do chamado no banco
     *
     * @param   Array    $ArDados   Contem todos os dados necessarios para criacao do chamado
     *
     * @return  Boolean
     * @since   Abril de 2012
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    public function savePhoneCalled($ArDados) {
        return $this->atendimentoDao->savePhoneCalled($ArDados);
    }

    /**
     * @method  findPhoneCalledsBySector
     *
     * Realiza a listagem completa de todos os chamados telefonicos. Apos a listagem
     * preenche cada entidade com objetos da Classe Setor, Cliente e Usuario para exibicao
     * de dados personalizados na view
     *
     * @return  Array
     * @since   Abril de 2012
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    public function findPhoneCalledsBySector() {
        $ArPhoneCalled = $this->atendimentoDao->findPhoneCalledsBySector();
        $this->fillCalled($ArPhoneCalled);
        return $ArPhoneCalled;
    }

    /**
     * @method  findCalledByFilter
     *
     * Realiza uma listagem com filtro do Chamado Telefonico baseado no ID do Filtro
     *
     * @param   String    $IDFilter     Tipo de Filtro que sera executado
     *
     * @return  Array
     * @since   Abril de 2012
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    public function findCalledByFilter($IDFilter, $filterType) {
        $ArCalled = array();
        if ($filterType == 'phone') {
            if ($IDFilter == self::PHONE_SECTOR) {
                $ArCalled = $this->atendimentoDao->findPhoneCalledsBySector();
            } else if ($IDFilter == self::PHONE_ALL) {
                $ArCalled = $this->atendimentoDao->findAllPhoneCalled();
            } else if ($IDFilter == self::OWNER_PHONE_CALLED) {
                $ArCalled = $this->atendimentoDao->findAllMyPhoneCalled();
            } else if ($IDFilter == self::LAST_20) {
                $ArCalled = $this->atendimentoDao->findLast20PhoneCalled();
            }
        } else if ($filterType == 'external') {
            if ($IDFilter == self::EXTERNAL_SECTOR) {
                $ArCalled = $this->atendimentoDao->findAllExternalCalledBySector();
            } else if ($IDFilter == self::EXTERNAL_PRIORITY) {
                $ArCalled = $this->atendimentoDao->findAllPriorityExternalCalled();
            } else if ($IDFilter == self::OWNER_EXTERNAL_CALLED) {
                $ArCalled = $this->atendimentoDao->findAllMyExternalCalled();
            } else if ($IDFilter == self::EXTERNAL_WAITING_CUSTOMER) {
                $ArCalled = $this->atendimentoDao->findAllMyExternalCalledWatingCustomer();
            }
        } else if ($filterType == 'internal') {
            if ($IDFilter == self::INTERNAL_SECTOR) {
                $ArCalled = $this->atendimentoDao->findInternalCalledBySector();
            } else if ($IDFilter == self::INTERNAL_ALL) {
                $ArCalled = $this->atendimentoDao->findAllInternalCalled();
            } else if ($IDFilter == self::INTERNAL_WAITING_CUSTOMER) {
                $ArCalled = $this->atendimentoDao->findAllMyInternalCalledWaintingCustomer();
            }
        } else if ( $filterType == 'cancelled' ) {
            if( $IDFilter == self::CANCELLED_WAITING_ANSWER ) {
                $ArCalled = $this->atendimentoDao->findAllCancelledCalled();
            } else if( $IDFilter == self::CANCELLED_WAITING_CUSTOMER) {
                $ArCalled = $this->atendimentoDao->findAllCancelledCalledWaitingCustomer();
            } else if( $IDFilter == self::CANCELLED_CLOSED ) {
                $ArCalled = $this->atendimentoDao->findAllClosedCancelledCalled();
            }
        }
        $this->fillCalled($ArCalled);
        return $ArCalled;
    }

    public function generateSearchParameters($ArSearchParameters) {
        $ArDados = array();
        foreach ($ArSearchParameters as $StKey => $MxParameters) {
            if (!empty($MxParameters)) {
                $ArDados[$StKey] = $MxParameters;
            }
        }
        if (!empty($ArDados['DtCriacao'])) {
            dateBRtoBD($ArDados['DtCriacao']);
        }
        if (!empty($ArDados['DtFechamento'])) {
            dateBRtoBD($ArDados['DtFechamento']);
        }
        return $ArDados;
    }

    public function searchCalledByFilter($ArDados) {
        $ArSearch = array();
        if( !empty($ArDados['IDChamado']) ) {
            $Chamado = $this->atendimentoDao->findById($ArDados['IDChamado']);
            $ArSearch = !empty($Chamado) ? array($Chamado) : false;
        } else {
            $ArSearch = $this->atendimentoDao->advancedSearch($ArDados);
        }
        $this->fillCalled($ArSearch);
        return $ArSearch;
    }

    public function findAllExternalCalledSector() {
        $ArList = $this->atendimentoDao->findAllExternalCalledBySector();
        $this->fillCalled($ArList);
        return $ArList;
    }

    public function findById($IDChamado) {
        $Chamado = $this->atendimentoDao->findById($IDChamado);
        $this->fillCalled($Chamado);
        return $Chamado;
    }

    public function updateCalled($ArDados) {
        return $this->atendimentoDao->updateCalledByFilter($ArDados);
    }

    public function insertNote($ArDados) {
        unset($ArDados['TxResposta']);
        $Mensagem = $this->mensagemService->generateMessage($ArDados);
        return $this->atendimentoDao->insertNote($Mensagem);
    }

    public function insertAnswer($ArDados) {
        unset($ArDados['TxObservacao']);
        $Mensagem = $this->mensagemService->generateMessage($ArDados);
        return $this->atendimentoDao->insertAnswer($Mensagem);
    }

    public function changeSector($ArDados) {
        $Sector = $this->setorService->findById($ArDados['IDNewSector']);
        $OldSector = $this->setorService->findById($ArDados['IDOldSector']);
        $Mensagem = $this->mensagemService->generateMessage($ArDados);
        $Mensagem->setTxMensagem(sprintf($Mensagem->getTxMensagem(), $OldSector->getStNome(), $Sector->getStNome()));
        return $this->atendimentoDao->changeSector($ArDados, $Mensagem);
    }

    public function changeResponsible($ArDados) {
        $Mensagem = $this->mensagemService->generateMessage($ArDados);
        if ($Mensagem->isType(AcaoChamado::TROCAR_RESPONSAVEL)) {
            $Usuario = $this->usuarioService->findById($ArDados['IDNewUser']);
            $Mensagem->setTxMensagem(sprintf($Mensagem->getTxMensagem(), $Usuario->getArDadosUsuario('StNome')));
        }
        return $this->atendimentoDao->changeResponsible($ArDados, $Mensagem);
    }

    public function findCalledByCustomer($IDCliente) {
        return $this->atendimentoDao->findCalledByCustomer($IDCliente);
    }

    public function findAllInternalCalled() {
        return $this->atendimentoDao->findAllInternalCalled();
    }

    public function findInternalCalledBySector() {
        $ArCalleds = $this->atendimentoDao->findInternalCalledBySector();
        $this->fillCalled($ArCalleds);
        return $ArCalleds;
    }

    private function fillCalled(&$MxCalled) {
        if (!empty($MxCalled)) {
            $this->fillCalledWithSector($MxCalled);
            $this->fillCalledWithCustomer($MxCalled);
            $this->fillCalledWithEmployee($MxCalled);
            $this->fillCalledWithEvaluation($MxCalled);
        }
    }

    public function fillCalledWithMessages($MxCalled) {
        if (!is_array($MxCalled)) {
            $MxCalled->setArMensagens($this->mensagemService->findByCalled($MxCalled->getIDChamado()));
            return;
        }
        foreach ($MxCalled as &$Chamado) {
            $Chamado->setArMensagens($this->mensagemService->findByCalled($Chamado->getIDChamado()));
        }
    }

    /**
     * @method  fillCalledWithSector
     *
     * Preenche o Chamado Telefonico com a instancia de seu Setor
     *
     * @param   Array    $ArPhoneCalled     Lista dos chamados telefonicos da ultima consulta
     *
     * @return  void
     * @since   Abril de 2012
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    private function fillCalledWithSector(&$MxCalled) {
        if (!is_array($MxCalled)) {
            $MxCalled->setSetor($this->setorService->findById($MxCalled->getIDSetor()));
            return;
        }
        foreach ($MxCalled as &$Chamado) {
            $Chamado->setSetor($this->setorService->findById($Chamado->getIDSetor()));
        }
    }

    /**
     * @method  fillCalledWithCustomer
     *
     * Preenche o Chamado Telefonico com a instancia de seu Cliente
     *
     * @param   Array    $ArPhoneCalled     Lista dos chamados telefonicos da ultima consulta
     *
     * @return  void
     * @since   Abril de 2012
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    private function fillCalledWithCustomer(&$MxCalled) {
        if (!is_array($MxCalled)) {
            if( !$MxCalled->isInternalCalled() ) {
                $MxCalled->setCliente($this->clienteService->findById($MxCalled->getIDCliente()));
            } else {
               $MxCalled->setCliente($this->usuarioService->findById($MxCalled->getIDCliente()));
            }
            return;
        }
        foreach ($MxCalled as &$Chamado) {
            if( !$Chamado->isInternalCalled() ) {
                $Chamado->setCliente($this->clienteService->findById($Chamado->getIDCliente()));
            } else {
               $Chamado->setCliente($this->usuarioService->findById($Chamado->getIDCliente()));
            }
        }
    }

    /**
     * @method  fillCalledWithEmployee
     *
     * Preenche o Chamado Telefonico com a instancia do Usuario que possui responsabilidade sobre ele
     *
     * @param   Array    $ArPhoneCalled     Lista dos chamados telefonicos da ultima consulta
     *
     * @return  void
     * @since   Abril de 2012
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    private function fillCalledWithEmployee(&$MxCalled) {
        if (!is_array($MxCalled)) {
            $MxCalled->setFuncionario($this->usuarioService->findSimpleUserById($MxCalled->getIDResponsavel()));
            return;
        }
        foreach ($MxCalled as &$Chamado) {
            $Chamado->setFuncionario($this->usuarioService->findSimpleUserById($Chamado->getIDResponsavel()));
        }
    }

    private function fillCalledWithEvaluation($MxCalled) {
        if (!is_array($MxCalled)) {
            $MxCalled->setAvaliacao($this->avaliacaoService->findByCalled($MxCalled->getIDChamado()));
            return;
        }
        foreach ($MxCalled as &$Chamado) {
            $Chamado->setAvaliacao($this->avaliacaoService->findByCalled($Chamado->getIDChamado()));
        }
    }

    public function generateReportFromLoggedUser($ArDates = false) {
        $IDUsuario = Dracosys::getLoggedUser()->getIDUsuario();
        $Report = array(
            'ExternalCalled' => $this->atendimentoDao->countNumberOfAnwernsExternalCalledFromLoggedUser($ArDates),
            'InternalCalled' => $this->atendimentoDao->countNumberOfAnwernsInternalCalledFromLoggedUser($ArDates),
            'PhoneCalled' => $this->atendimentoDao->countNumberOfAnwernsPhoneCalledFromLoggedUser($ArDates),
            'CustomerRegister' => $this->clienteService->countNumberOfCustomerRegisterByLoggedUser($ArDates),
            'Evaluation' => $this->avaliacaoService->countEvaluationByUser($IDUsuario, $ArDates),
            'PerfectCalled' => $this->atendimentoDao->countNumberOf1AnswerClosedCalledByUser($IDUsuario, $ArDates),
            'WaitingCustomerCalled' => $this->atendimentoDao->countNumberOfNotClosedCalledByUser($IDUsuario, $ArDates)
        );
        return $Report;
    }

    public function saveInternalCalled($ArDados) {
        return $this->atendimentoDao->saveInternalCalled($ArDados);
    }

    public function generateIndividualReport($ArPeriod = false) {
        $ArUsers = $this->usuarioService->findAll(true);
        foreach ($ArUsers as &$Usuario) {
            $Report = array(
                'INTERNO' => $this->atendimentoDao->countNumberOfInternalAnswersByUser($Usuario->getIDUsuario(), $ArPeriod),
                'EXTERNO' => $this->atendimentoDao->countNumberOfExternalAnswersByUser($Usuario->getIDUsuario(), $ArPeriod),
                'TELEFONICO' => $this->atendimentoDao->countNumberOfPhoneCalledByUser($Usuario->getIDUsuario(), $ArPeriod),
                'CLIENTES_CADASTRADOS' => $this->clienteService->countNumberOfCustomerRegisterByUser($Usuario->getIDUsuario(), $ArPeriod),
                'AVALIACAO' => $this->avaliacaoService->countEvaluationByUser($Usuario->getIDUsuario(), $ArPeriod),
                'CHAMADOS_NAO_FECHADOS' => $this->atendimentoDao->countNumberOfNotClosedCalledByUser($Usuario->getIDUsuario(), $ArPeriod),
                'FINALIZADOS_1_RESPOSTA' => $this->atendimentoDao->countNumberOf1AnswerClosedCalledByUser($Usuario->getIDUsuario(), $ArPeriod)
            );
            $Usuario->setReport($Report);
        }
        return $ArUsers;
    }

    public function generateReportByFilter($filterType, $ArPeriod) {
        $ArCalled = array();
        if ($filterType == 'individualReport') {
            $ArCalled = $this->generateIndividualReport($ArPeriod['Date']);
        } else if($filterType == 'pessoalReport') {
            $ArCalled = $this->generateReportFromLoggedUser($ArPeriod['Date']);
        } else if($filterType == 'sectorReport') {
            $ArCalled = $this->generateSectorReport($ArPeriod['Date']);
        } else if($filterType == 'departamentReport') {
            $ArCalled = $this->generateDepartamentReport($ArPeriod['Date']);
        }

        return $ArCalled;
    }

    public function findAllCancelledCalled() {
        $ArCalled = $this->atendimentoDao->findAllCancelledCalled();
        $this->fillCalled($ArCalled);
        return $ArCalled;
    }

    public function generateSectorReport($ArPeriod = false) {
        $ArSectors = $this->setorService->findAll(true);
        foreach($ArSectors as &$Sector) {
            $Report = array(
                'INTERNO' => $this->atendimentoDao->countNumberOfInternalAnswersBySector($Sector->getIDSetor(), $ArPeriod),
                'EXTERNO' => $this->atendimentoDao->countNumberOfExternalAnswersBySector($Sector->getIDSetor(), $ArPeriod),
                'TELEFONICO' => $this->atendimentoDao->countNumberOfPhoneCalledBySector($Sector->getIDSetor(), $ArPeriod),
                'CLIENTES_CADASTRADOS' => $this->clienteService->countNumberOfCustomerRegisterBySector($Sector->getIDSetor(), $ArPeriod),
                'AVALIACAO' => $this->avaliacaoService->countEvaluationBySector($Sector->getIDSetor(), $ArPeriod),
                'CHAMADOS_NAO_FECHADOS' => $this->atendimentoDao->countNumberOfNotClosedCalledBySector($Sector->getIDSetor(), $ArPeriod),
                'FINALIZADOS_1_RESPOSTA' => $this->atendimentoDao->countNumberOf1AnswerClosedCalledBySector($Sector->getIDSetor(), $ArPeriod)
            );
            $Sector->setReport($Report);
        }
        return $ArSectors;
    }

    public function generateDepartamentReport($ArPeriod = false) {
        $ArDepartaments = $this->departamentoService->findAll();
        foreach($ArDepartaments as &$Departamento) {
            $Report = array(
                'INTERNO' => $this->atendimentoDao->countNumberOfInternalAnswersByDepartament($Departamento->getIDDepartamento(), $ArPeriod),
                'EXTERNO' => $this->atendimentoDao->countNumberOfExternalAnswersByDepartament($Departamento->getIDDepartamento(), $ArPeriod),
                'TELEFONICO' => $this->atendimentoDao->countNumberOfPhoneCalledByDepartament($Departamento->getIDDepartamento(), $ArPeriod),
                'CLIENTES_CADASTRADOS' => $this->clienteService->countNumberOfCustomerRegisterByDepartament($Departamento->getIDDepartamento(), $ArPeriod),
                'AVALIACAO' => $this->avaliacaoService->countEvaluationByDepartament($Departamento->getIDDepartamento(), $ArPeriod),
                'CHAMADOS_NAO_FECHADOS' => $this->atendimentoDao->countNumberOfNotClosedCalledByDepartament($Departamento->getIDDepartamento(), $ArPeriod),
                'FINALIZADOS_1_RESPOSTA' => $this->atendimentoDao->countNumberOf1AnswerClosedCalledByDepartament($Departamento->getIDDepartamento(), $ArPeriod)
            );
            $Departamento->setReport($Report);
        }
        return $ArDepartaments;
    }

    public function closeCalled($IDChamado){
        $ArFilter = array('IDChamado'=>$IDChamado, 'EnStatus'=>'FECHADO', 'DtFechamento' => now());
        $Mensagem = $this->mensagemService->generateMessage($ArFilter);
        return $this->atendimentoDao->closeCalled($ArFilter, $Mensagem);
    }

    public function generateCalledReportByCustomer($IDCliente) {
        $ArCalleds = $this->findCalledByCustomer($IDCliente);
        $ArCalledTypeReport = array('EXTERNO' => 0, 'TELEFONICO' => 0, 'CANCELAMENTO' => 0, 'EXTERNO_FECHADO' => 0);
        foreach($ArCalleds as $Called) {
            $ArCalledTypeReport[ $Called->getEnTipoChamado() ]++;
            if( $Called->isExternalCalled() && $Called->isClosed() ) {
                $ArCalledTypeReport['EXTERNO_FECHADO']++;
            }
        }
        $ArCalledTypeReport['TOTAL'] = array_sum($ArCalledTypeReport) - $ArCalledTypeReport['EXTERNO_FECHADO'];
        return $ArCalledTypeReport;
    }

    public function addToFavourite($IDChamado) {
        $Usuario = Dracosys::getLoggedUser();
        if( !$this->atendimentoDao->addToFavourite($IDChamado, $Usuario->getIDUsuario()) ) {
            return false;
        }
        $Usuario->addCalledToFavourite($this->findById($IDChamado));
        Dracosys::saveSessionValue(SESSION_SYSTEM, 'Usuario', $Usuario);
        return true;
    }

    public function removeFromFavourite($IDChamado) {
        $Usuario = Dracosys::getLoggedUser();
        if( !$this->atendimentoDao->removeFromFavourite($IDChamado, $Usuario->getIDUsuario()) ) {
            return false;
        }
        $Usuario->removeCalledFromFavourite($IDChamado);
        Dracosys::saveSessionValue(SESSION_SYSTEM, 'Usuario', $Usuario);
        return true;
    }

    public function findCalledByMessage($IDMensagem) {
        $Chamado = $this->atendimentoDao->findCalledByMessage($IDMensagem);
        $this->fillCalled($Chamado);
        return $Chamado;
    }

    public function readingCalled($IDChamado) {
        return $this->atendimentoDao->readingCalled($IDChamado);
    }

    public function notReadingCalled($IDChamado) {
        return $this->atendimentoDao->notReadingCalled($IDChamado);
    }

    public function isReading($IDChamado) {
        return $this->atendimentoDao->isReading($IDChamado);
    }

}


?>
